<?php
/**
 * Created by PhpStorm.
 * User: George
 * Date: 2017/10/18
 * Time: 17:09
 */

namespace AdminBundle\Services;

use Redis;

class CacheTask
{
    const KEY_QUEUE_LOG = 'report';
    private static $instace;
    private $config = [];
    private $redis = null;

    private function __construct($config = [])
    {
        $defaultConfig = ['host' => '', 'port' => 6379, 'auth' => '', 'timeout' => 0.0, 'db' => 2];
//        $config = array_merge_recursive($defaultConfig, $config);
        $config = $config + $defaultConfig;
        if (empty($config['host'])) {
            throw new \RedisException('host error.');
        }
        $this->config = $config;
    }

    public function __clone()
    {
        // TODO: Implement __clone() method.
        trigger_error("forbidden", E_USER_ERROR);
    }

    public static function getInstance($config)
    {
        if ((self::$instace instanceof self) == false) {
            self::$instace = new self($config);
        }
        return self::$instace;
    }


    private function initRedis($config)
    {
        $redis = new Redis();
        if ($redis->connect($config['host'], $config['port'], $config['timeout']) == false) {
            throw new \RedisException('redis server was shutdown.');
        }
        if (!empty($config['auth'])) {
            if ($redis->auth($config['auth']) == false) {
                throw new \RedisException('auth error.');
            }
        }
        $redis->select($config['db']);

        $this->redis = $redis;
        return $this->redis;
    }

    public function destroyRedis()
    {
        if ($this->redis) {
            $this->redis->close();
            unset($this->redis);
        }
    }

    private function getRedis()
    {
        if ($this->redis == null) {
            return $this->initRedis($this->config);
        }
        return $this->redis;
    }

    private function setRedisWithSorted($key, $score, $value)
    {
        $redis = $this->getRedis();
        $redis->zAdd($key, $score, $value);
        return $this;
    }

    private function setRedisWithHash($key, $field, $value)
    {
        $redis = $this->getRedis();
        $ret = $redis->hSet($key, $field, $value);
        return $this;
    }

    private function delByKeyAndField($key, $field)
    {
        $redis = $this->getRedis();
        return $redis->hDel($key, $field);
    }

    public function clearTaskByUserName($em, $userName, $queueIds)
    {
        foreach ($queueIds as $id) {
            $this->delByKeyAndField($userName, $id);
        }
        $em->getRepository('AdminBundle:TaskQueueWaiting')->deleteDelivery($queueIds);
    }

    public function taskByUserName($userName)
    {
        $redis = $this->getRedis();
        return $redis->hVals($userName);
    }

    public function taskLogPop()
    {
        $redis = $this->getRedis();
        return $redis->lPop(self::KEY_QUEUE_LOG);
    }

    public function taskLog($userName, $id, $task)
    {
        $redis = $this->getRedis();
//        $value = $redis->hGet($userName, $id);
//        if ($value == null) {
//            return 0;
//        }
        $redis->hDel($userName, $id);
        return $redis->rPush(self::KEY_QUEUE_LOG, json_encode($task));
    }

    public function taskPublish($em, $condition = [])
    {
        if (empty($condition)) {
            $condition = ['ctime' => date('Y-m-d H:i:s', time() - 120)];
        }
        $taskQueueWaitings = $em->getRepository('AdminBundle:TaskQueueWaiting')
            ->cachePublish($condition);

        if ($taskQueueWaitings == null)
            return [];
        foreach ($taskQueueWaitings as $taskQueueWaiting) {

            $this->setRedisWithHash(
                $taskQueueWaiting->getWebchatUsername(),
                $taskQueueWaiting->getId(),
                $taskQueueWaiting->toTask());
        }
        return count($taskQueueWaitings);
    }

}